﻿using System;

namespace Storyteller.Framework
{
	public enum ScreenState
	{
		Waiting,
		TransitionOn,
		Active,
		TransitionOff,
	}

	public abstract class GameScreen
	{
		public ScreenState ScreenState { get; set; }

		public ScreenManager ScreenManager { get; protected set; }

		public bool IsExclusive { get; protected set; }
		public bool NeedsRemoved { get; protected set; }
		public bool HasFocus { get; protected set; }
		
		public bool TransitionOn { get; protected set; }
		public bool TransitionOff { get; protected set; }
		
		public float TransitionOnTime { get; protected set; }
		public float TransitionOffTime { get; protected set; }
		public float TransitionPosition { get; protected set; }

		public GameScreen(ScreenManager screenManager)
		{
			ScreenManager = screenManager;
			IsExclusive = true;
			NeedsRemoved = false;
			TransitionOn = TransitionOff = false;
			TransitionOnTime = TransitionOffTime = TransitionPosition = 0;
		}
		
		public void Reset()
		{
			TransitionPosition = 0;
			NeedsRemoved = false;
		}

		public void Update(float deltaSeconds, bool hasFocus)
		{
			HasFocus = hasFocus;

			switch (ScreenState)
			{
				case ScreenState.Waiting:
					if (TransitionOn)
					{
						TransitionPosition = 0;
						ScreenState = ScreenState.TransitionOn;
						OnTransitionOn(TransitionOnTime);
					}
					else
					{
						TransitionPosition = 1;
						ScreenState = ScreenState.Active;
					}
					return;

				case ScreenState.TransitionOn:
					TransitionPosition += deltaSeconds / TransitionOnTime;
					if (TransitionPosition >= 1)
					{
						TransitionPosition = 1;
						ScreenState = ScreenState.Active;
					}
					break;

				case ScreenState.TransitionOff:
					TransitionPosition -= deltaSeconds / TransitionOffTime;
					if (TransitionPosition <= 0)
					{
						TransitionPosition = 0;
						NeedsRemoved = true;
					}
					break;

				default:
					break;
			}

			Update(deltaSeconds);
		}

		public void ExitScreen(bool allowTransition)
		{
			if (!allowTransition || TransitionOff == false)
			{
			    NeedsRemoved = true;
			}
			else
			{
			    ScreenState = ScreenState.TransitionOff;
				OnTransitionOff(TransitionOffTime);
			}
		}
		
		public virtual void OnAdd() { }
		public virtual void OnRemove() { }
		public virtual void OnTransitionOn(float time) { }
		public virtual void OnTransitionOff(float time) { }
		
		public abstract void Update(float deltaSeconds);
		public abstract void Draw();
	}
}
